<template>
  <n-drawer v-model:show="visible" :width="500" placement="right" @update:show="handleVisibleChange">
    <n-drawer-content :title="isEdit ? '编辑菜单' : '新增菜单'">
      <n-form ref="formRef" :model="formModel" :rules="rules" label-placement="left" label-width="120px"
        require-mark-placement="right-hanging">
        <n-form-item label="菜单类型">
          <n-radio-group v-model:value="formModel.menuType" @update:value="handleChangeMenuType">
            <n-radio v-for="item in MENUS_TYPES_LIST" :key="item.value" :value="item.value">
              {{ item.name }}
            </n-radio>
          </n-radio-group>
        </n-form-item>

        <n-form-item :label="isButton ? '按钮/权限' : '菜单名称'" path="name" :required="true">
          <n-input v-model:value="formModel.name" placeholder="请输入菜单名称" clearable />
        </n-form-item>

        <n-form-item label="上级菜单" path="parentId" :required="true" v-if="!isDir">
          <n-tree-select :options="allMenus" v-model:value="formModel.parentId" label-field="name" />
        </n-form-item>

        <n-form-item label="访问路径" path="url">
          <n-input v-model:value="formModel.url" placeholder="请输入访问路径" clearable />
        </n-form-item>

        <n-form-item label="前端组件" path="component" :required="true" v-if="!isButton">
          <n-input v-model:value="formModel.component" placeholder="请输入前端组件" clearable />
        </n-form-item>

        <n-form-item label="组件名称" path="componentName" v-if="!isButton">
          <n-input v-model:value="formModel.componentName" placeholder="请输入组件名称" clearable>
            <template #suffix>
              <n-tooltip trigger="hover" placement="top">
                <template #trigger>
                  <n-icon><info-outlined /></n-icon>
                </template>
                <div>
                  <div>组件名称用于标识页面组件</div>
                  <div>组件名称不能重复，主要用于路由缓存功能。</div>
                  <div>
                    如果组件名称和vue组件的name属性不一致，则会导致路由缓存失效。
                  </div>
                  <div>非必填，留空则会根据访问路径自动生成。</div>
                </div>
              </n-tooltip>
            </template>
          </n-input>
        </n-form-item>

        <n-form-item label="菜单图标" path="icon" v-if="!isButton">
          <n-input-group>
            <n-input v-model:value="formModel.icon" placeholder="请选择菜单图标" readonly style="width: 85%">
              <template #prefix v-if="formModel.icon">
                <n-icon>
                  <component :is="getIconComponent(formModel.icon)" v-if="getIconComponent(formModel.icon)" />
                </n-icon>
              </template>
            </n-input>
            <n-button type="primary" style="width: 15%" @click="handleShowIconPicker">
              <n-icon><search-outlined /></n-icon>
            </n-button>
          </n-input-group>
        </n-form-item>

        <n-form-item label="排序" path="sortNo" v-if="!isButton">
          <n-input-number v-model:value="formModel.sortNo" placeholder="请输入排序" clearable :min="0" style="width: 100%" />
        </n-form-item>

        <n-form-item label="是否路由菜单" v-if="!isButton">
          <n-switch v-model:value="formModel.route" />
        </n-form-item>

        <n-form-item label="隐藏路由" v-if="!isButton">
          <n-switch v-model:value="formModel.hidden" />
        </n-form-item>

        <n-form-item label="是否缓存路由" v-if="!isButton">
          <n-switch v-model:value="formModel.keepAlive" />
        </n-form-item>

        <n-form-item label="授权标识" path="perms" :required="true" v-if="isButton">
          <n-input v-model:value="formModel.perms" placeholder="请输入授权标识" clearable />
        </n-form-item>

        <n-form-item label="授权策略" v-if="isButton">
          <n-radio-group v-model:value="formModel.permsType">
            <n-radio value="1">可见/可访问</n-radio>
            <n-radio value="2">可编辑</n-radio>
          </n-radio-group>
        </n-form-item>

        <n-form-item label="状态" v-if="isButton">
          <n-radio-group v-model:value="formModel.status">
            <n-radio value="1">有效</n-radio>
            <n-radio value="0">无效</n-radio>
          </n-radio-group>
        </n-form-item>
      </n-form>

      <template #footer>
        <n-space>
          <n-button @click="handleCancel">取消</n-button>
          <n-button type="primary" @click="handleConfirm" :loading="loading">
            确认
          </n-button>
        </n-space>
      </template>
    </n-drawer-content>
  </n-drawer>

  <!-- 图标选择器 -->
  <icon-picker v-model:show="showIconPicker" @select="handleSelectIcon" />
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch } from "vue";
import { FormInst, useMessage } from "naive-ui";
import { InfoOutlined, SearchOutlined } from "@vicons/material";
import { addMenu, editMenu } from "@/api/menus/menus.api";
import { MENUS_TYPES_LIST, MENUS_TYPES } from "@/constants/menus";
import IconPicker from "@/components/biz/iconPicker/index.vue";
import * as AntdIcons from "@vicons/antd";

const props = defineProps({
  show: {
    type: Boolean,
    default: false,
  },
  menuData: {
    type: Object,
    default: () => ({}),
  },
  isEdit: {
    type: Boolean,
    default: false,
  },
  allMenus: {
    type: Array,
    default: () => [],
  },
});

const emit = defineEmits(["update:show", "submit", "cancel"]);

const visible = computed({
  get: () => props.show,
  set: (val) => emit("update:show", val),
});

const isDir = computed(() => {
  return (formModel.menuType as any) * 1 === 0;
});

const isMenu = computed(() => {
  return (formModel.menuType as any) * 1 === 1;
});

const isButton = computed(() => {
  return (formModel.menuType as any) * 1 === 2;
});

const message = useMessage();
const formRef = ref<FormInst | null>(null);
const loading = ref(false);

// 表单数据
const formModel = reactive({
  id: "",
  menuType: MENUS_TYPES["0"].value,
  name: "",
  parentId: "",
  url: "",
  component: "",
  componentName: "",
  icon: "",
  sortNo: 1,
  route: true,
  hidden: false,
  keepAlive: false,
  perms: "",
  permsType: "1",
  status: "1",
});

// 表单验证规则
const rules = {
  name: [
    { required: true, message: "请输入菜单名称", trigger: ["blur", "input"] },
  ],
  parentId: [
    {
      required: (formValue: any) => formValue.menuType !== "0",
      message: "请选择上级菜单",
      trigger: ["blur", "change"],
    },
  ],
  component: [
    {
      required: (formValue: any) => formValue.menuType !== "2",
      message: "请输入前端组件",
      trigger: ["blur", "input"],
    },
  ],
  perms: [
    {
      required: (formValue: any) => formValue.menuType === "2",
      message: "请输入授权标识",
      trigger: ["blur", "input"],
    },
  ],
};

// 监听编辑状态，填充表单数据
watch(
  () => props.menuData,
  (newVal) => {
    if (newVal && Object.keys(newVal).length > 0) {
      Object.assign(formModel, newVal);
    }
  },
  { immediate: true, deep: true }
);

const handleVisibleChange = (val: boolean) => {
  if (!val) {
    // 当抽屉关闭时，重置表单
    resetForm();
    emit("cancel");
  }
};

// 重置表单
const resetForm = () => {
  formModel.id = "";
  formModel.menuType = MENUS_TYPES["0"].value;
  formModel.name = "";
  formModel.parentId = "";
  formModel.url = "";
  formModel.component = "";
  formModel.componentName = "";
  formModel.icon = "";
  formModel.sortNo = 1;
  formModel.route = true;
  formModel.route = true;
  formModel.hidden = false;
  formModel.keepAlive = false;
  formModel.perms = "";
  formModel.permsType = "1";
  formModel.status = "1";

  if (formRef.value) {
    formRef.value.restoreValidation();
  }
};

const handleChangeMenuType = () => {
  if (
    isMenu.value &&
    !formModel.id &&
    (formModel.component == "Layout" ||
      formModel.component == "layouts/default/index" ||
      formModel.component == "layouts/RouteView")
  ) {
    formModel.component = "";
  }
};

// 取消操作
const handleCancel = () => {
  visible.value = false;
  resetForm();
  emit("cancel");
};

// 确认提交
const handleConfirm = () => {
  formRef.value?.validate(async (errors) => {
    if (errors) {
      message.error("请完善表单信息");
      return;
    }

    loading.value = true;

    try {
      if (!props.isEdit) {
        // 新增菜单
        const result = await addMenu(formModel);
        if (result && result.success) {
          message.success("菜单添加成功");
          emit("submit", { ...formModel });
          visible.value = false;
          resetForm();
        } else {
          message.error(result?.message || "菜单添加失败");
        }
      } else {
        // 编辑菜单
        const result = await editMenu(formModel);
        if (result && result.success) {
          message.success("菜单编辑成功");
          emit("submit", { ...formModel });
          visible.value = false;
          resetForm();
        } else {
          message.error(result?.message || "菜单编辑失败");
        }
      }
    } catch (error) {
      console.error("操作失败", error);
      message.error("操作失败，请稍后重试");
    } finally {
      loading.value = false;
    }
  });
};

const showIconPicker = ref(false);

// 显示图标选择器
const handleShowIconPicker = () => {
  showIconPicker.value = true;
};

// 处理图标选择
const handleSelectIcon = (iconName: string) => {
  formModel.icon = iconName;
};

// 获取图标组件
const getIconComponent = (iconName: string) => {
  if (!iconName) return null;
  return AntdIcons[iconName] || null;
};
</script>

<style scoped>
.drawer-footer {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 10px 20px;
  text-align: right;
  background-color: #fff;
  border-top: 1px solid #f0f0f0;
  left: 0;
}
</style>
